// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Copyright (C) 2008 Vignette Corporation  All rights reserved.
// THIS PROGRAM IS CONFIDENTIAL AND AN UNPUBLISHED WORK AND TRADE SECRET
// OF THE COPYRIGHT HOLDER, AND DISTRIBUTED ONLY UNDER RESTRICTION.
// EXCEPT AS EXPLICITLY STATED IN A WRITTEN AGREEMENT BETWEEN THE PARTIES,
// THE SOFTWARE IS PROVIDED AS-IS, WITHOUT WARRANTIES OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// NONINFRINGEMENT, PERFORMANCE, AND QUALITY.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

import com.vignette.community.client.services.common.RemoteObjectEntity;
import com.vignette.community.client.services.common.XAPIConstants;
import com.vignette.community.client.services.dataservice.*;
import com.vignette.community.client.services.util.Util;
import com.vignette.community.client.services.util.HeaderData;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Community Data example - working with binary content. </br></br> For this example
 * to work the <code>vgncommsvcs.properties</code> should be found in the
 * classpath and should contain an entry based on the following: </br> <code>
 * CommunityServer1=collab,1,&lt;community_server_host&gt;,&lt;community_server_port&gt;,/xapi/,/xapi/,com.vignette.community.client.services.security.VssSecurityHandler,vssKey=changeme
 * </code>
 */
public class CDataBinaryContent {
  
    public static final String SAMPLE_FILE_NAME = "ORIGINAL_FILE_NAME.EXT";

    public String createRemoteObject(CommunityDataServiceIf dservice, RemoteObjectEntity ro) {

        String ROName = "What is the most popular sport?";
        String RODescription = "Story comparing popular sports";

        Action createAction = new CreateNewAction();
        ActionData remoteActionData =
                new RemoteObjectActionData(ROName,
                        RODescription,
                        ro);
        RemoteObjectQueryCreate createQuery =
                new RemoteObjectQueryCreate(ro,
                        createAction,
                        remoteActionData,
                        false);
        Response response1 = dservice.query(createQuery);
        if (response1 != null
                && response1.getResponseCode()
                == HttpServletResponse.SC_MOVED_PERMANENTLY) {
            return Util.getRedirectOid(response1);
        }
        return null;
    }

    private String uploadFileOnRemoteObject(CommunityDataServiceIf dservice, String oid) {
        String documentOid = null;
        Action uploadAction = new NewUploadAction();

        Map parameters = new HashMap();
        parameters.put(XAPIConstants.NameFieldName, new String[]{"document_name"});
        parameters.put(XAPIConstants.ObjectFieldName, new String[]{oid});
        ActionData uploadActionData = new UploadActionData(parameters);

        // add extra upload data
        byte[] bytes = new byte[]{(byte)0x12, (byte)0x0F, (byte)0xF0};
        InputStream inputs = new ByteArrayInputStream(bytes);
        ((UploadActionData) uploadActionData).setInputStream(inputs);
        ((UploadActionData) uploadActionData).setSize(bytes.length);
        ((UploadActionData) uploadActionData).setName(SAMPLE_FILE_NAME) ;
        ((UploadActionData) uploadActionData).setContentType("text/plain");

        Response response1 = dservice.execute(uploadAction, uploadActionData);
        if (response1 != null && response1.getResponseCode()
            != HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
            documentOid = Util.getRedirectOid(response1);
        }
        return documentOid;
    }

    private void replaceFile(CommunityDataServiceIf dservice, String docoid) {
      Action action = new ReplaceUploadAction();

      Map parameters = new HashMap();
      parameters.put(XAPIConstants.ObjectFieldName, new String[]{docoid});
      parameters.put(XAPIConstants.NameFieldName, new String[]{"document_name"});
      parameters.put(XAPIConstants.TypeFieldName, new String[]{"DocumentObject"});
      ActionData data = new UploadActionData(parameters);

      // replace the content
      byte[] bytes = new byte[]{(byte)0x13, (byte)0x14, (byte)0x15, (byte)0x0F, (byte)0xF0};
      InputStream inputs = new ByteArrayInputStream(bytes);
      ((UploadActionData) data).setInputStream(inputs);
      ((UploadActionData) data).setSize(bytes.length);
      ((UploadActionData) data).setContentType("text/plain");
      ((UploadActionData) data).setName(SAMPLE_FILE_NAME) ;

      Response response1 = dservice.execute(action, data);
      if (response1 != null && response1.getResponseCode()
          != HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
          String documentOid = Util.getRedirectOid(response1);
      }
    }

    private String getFilesOnRemoteObject(CommunityDataServiceIf dservice, RemoteObjectEntity roEntity) {
      String responseXML = null;
      Query query = new RemoteObjectQuery(roEntity);
      query.addAdditionalParam(XAPIConstants.INCLUDES,XAPIConstants.CHILDREN);
      query.addAdditionalParam(XAPIConstants.INCLUDES,XAPIConstants.OPERATIONS);
      query.addAdditionalParam(XAPIConstants.CHILDREN_PAGINATION, "10");
      query.addAdditionalParam(XAPIConstants.CHILDREN_PAGINATION, "1");
      query.addAdditionalParam(XAPIConstants.CHILDREN_INCLUDES, XAPIConstants.OPERATIONS);
      query.addAdditionalParam(XAPIConstants.CHILDREN_SORT_DIRECTION, XAPIConstants.SORT_DIRECTION_DESC);

      Response content = dservice.query(query);
      if (content != null && content.getResponseCode() == HttpServletResponse.SC_OK) {
        responseXML = content.getData();
        // Parse out the tags from this XML response.
        // XML response contains all children objects, should filter using the objectType child property
        // e.g. objectType=='BinaryDocumen'||objectType=='ASCIIDocument'||objectType=='HTMLDocument'
      }

      return responseXML;
      
    }

    private void downloadFile(CommunityDataServiceIf dservice, String docoid, String fileName) {
        String encodedName = Util.escapifyNonData(fileName, true);
        String basicRequest = "/gm/document-" + docoid + "/" + encodedName;
        Response fileGetResponse = dservice.getClientService().fileGet(basicRequest);

        // Get content type etc. headers
        HeaderData[] headers = fileGetResponse.getResponseHeaders();
        
        // Get binary content
        InputStream in = fileGetResponse.getDataInputStream();

    }

    public static void main(String[] args) {

        String communityServerId = "CommunityServer1";
        String currentUser = "admin";
        String password = null;

        CDataBinaryContent cdata = new CDataBinaryContent();

        CommunityDataServiceIf dservice =
                CommunityDataServiceFactory.getInstance()
                        .createCommunityDataService(communityServerId,
                                currentUser,
                                password);

        // Create a Remote Object
        String extobjid = "3333338891-3";
        String extobjcontext = "Sports Channel";
        String extsystemid = "1";
        String extsystemtype = "CMS";
        String extrealm = "News Site";
        String extobjtype = "Article";
        String otherval = XAPIConstants.EXT_OBJ_STATUS
                + "="
                + XAPIConstants.DEV_STATUS;

        RemoteObjectEntity ro = new RemoteObjectEntity(extobjid,
                extobjcontext, extsystemtype,
                extsystemid, extrealm, extobjtype,
                otherval);

        String oid = cdata.createRemoteObject(dservice, ro);

        String docoid = cdata.uploadFileOnRemoteObject(dservice, oid);
        cdata.getFilesOnRemoteObject(dservice, ro);
        cdata.replaceFile(dservice, docoid);
        cdata.downloadFile(dservice, docoid, SAMPLE_FILE_NAME);

    }

}
